using System;
using System.Runtime.Serialization;

using BLToolkit.Mapping;

using TrueCode.Core.Aspects;
using TrueCode.Core.EditableEntity;
using TrueCode.Core.Validation;

namespace EMan.Common.EnterpriseStructure
{
  /// <remarks> <see cref="DataContract.IsReference"/> is set to true in order to be able to serialize cyclic 
  /// references - parent references its children and vise versa</remarks>
  [DataContract(IsReference = true)]
  [MapField("DepartmentId", "Department.Id")]
  [MapField("JobId", "Job.Id")]
  public class Employee : ReferenceEntity< Employee >
  {
    private static int _idgen = -1;

    public Employee( Job job, Department department, string nickName, string firstName, string surName, string secondName = null)
        : this( Guid.NewGuid(), _idgen--, nickName, firstName, secondName, surName )
    {
      Department = department;
      Job = job;
    }

    private Employee( Guid key, int id, string nickName, string firstName, string secondName, string surName )
    {
      Key = key;
      Id = id;
      NickName = nickName;
      Firstname = firstName;
      Secondname = secondName;
      Surname = surName;
    }

    [DataMember]
    [Validate.NotEmpty, Validate.MaxLength(50)]
    [Editable(EditableMode.ReadWrite)]
    public string NickName  { get; set; }

    [DataMember]
    [Validate.NotEmpty, Validate.MaxLength(50)]
    [Editable(EditableMode.All)]
    public string Firstname  { get; set; }

    [DataMember]
    [NullValue( null )]
    [Validate.MaxLength(50)]
    [Editable(EditableMode.All)]
    public string Secondname { get; set; }

    [DataMember]
    [Validate.NotEmpty, Validate.MaxLength(50)]
    [Editable(EditableMode.All)]
    public string Surname    { get; set; }

    [DataMember]
    [ Editable( EditableMode.ReadWrite ) ]
    public Department Department { get; set; }

    [DataMember]
    [Editable(EditableMode.ReadWrite)]
    public Job Job{ get; set; }

    public Employee Copy()
    {
      return new Employee( Key, Id, NickName, Firstname, Secondname, Surname );
    }

    #region BLT
    [Obsolete( "This constructor is for BLT and Tests only"), UsedImplicitly]
    public Employee() : this( Guid.NewGuid(), int.MinValue, null, null, null, null ){}
    #endregion
  }
}